﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NWN.GDY.Service.DataAccess;
using NWN.GDY.Service.Entity;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using NWN.GDY.Service.Common;
using Sdo.Payment.Common;
using NWN.GDY.Service.Core.HandcardCreator;

namespace NWN.GDY.Service.Core
{
    public class RoomBC
    {
        private static ICacheManager cache = CacheFactory.GetCacheManager();
        readonly string _prf = "_Room_";
        private RoomDA roomda = new RoomDA();

        private static volatile List<Card> Cards = null;
        private static object lockObj = new object();

        public static List<Card> GetCardsInstance()
        {
            lock (lockObj)
            {
                if (Cards == null)
                {
                    Cards = new RoomDA().GetCardsInfo();
                }
                return Cards;
            }
        }

        public List<Room> GetRooms(int RoomType)
        {
            List<Room> rooms = (List<Room>)cache.GetData(_prf + "List_" + RoomType.ToString() + "_");
            if (rooms != null)
                return rooms;
            rooms = roomda.GetRooms(RoomType);
            cache.Add(_prf + "List_" + RoomType.ToString() + "_", rooms, CacheItemPriority.High, null, new AbsoluteTime(TimeSpan.FromSeconds(GDYConfig.CacheRoomList)));
            return rooms;
        }

        public Room GetRoom(string RoomGUID)
        {
            Room room = (Room)cache.GetData(_prf + "Single_" + RoomGUID + "_");
            if (room != null)
                return room;
            room = roomda.GetRoom(RoomGUID);
            cache.Add(_prf + "Single_" + RoomGUID + "_", room);
            return room;
        }

        public int EnterRoom(string uid, string passport, string roomguid)
        {
            if (string.IsNullOrEmpty(uid))
                return GDYConsts.ReturnDefine.EmptyUserID;
            if (string.IsNullOrEmpty(roomguid))
                return GDYConsts.ReturnDefine.EmptyRoomGUID;
            return roomda.EnterRoom(uid, passport, roomguid);
        }

        public Room GetRoom(string RoomGUID, string userid, long recordid, string vplayrecord, string vroom, string vround, string vucoin, string vuroom, string vuinfo, long chatid, string vchat, string vadminroom, string vroundresult)
        {
            return roomda.GetRoom(RoomGUID, userid, recordid, vplayrecord, vroom, vround, vucoin, vuroom, vuinfo, chatid, vchat, vadminroom, vroundresult);
        }

        public int Sit(string uid, string roomguid, int SeatID)
        {
            return roomda.Sit(uid, roomguid, SeatID);
        }

        public int Stand(string uid, string roomguid)
        {
            return roomda.Stand(uid, roomguid);
        }

        public int Ready(string uid, string roomguid)
        {
            return roomda.Ready(uid, roomguid);
        }

        public int Pass(string uid, string roomguid, string roundguid)
        {
            return roomda.Pass(uid, roomguid, roundguid);
        }

        //public void Discard(string outcards, string lastcardnums, string lastuser, bool iszhuang, string currentuser)
        public string Discard(string UserID, string CardID, string ArrageCardID, string roomGUID, string RoundGUID, string lastcardids, int lasttype)
        {
            if((string.IsNullOrEmpty(lastcardids)&&lasttype>0)||(!string.IsNullOrEmpty(lastcardids)&&lasttype<=0))
                return GDYConsts.ReturnDefine.HANDCARDCHANGED.ToString();
            int iOut;
            Log.Lw("出牌：" + UserID + "_" + CardID + "_" + ArrageCardID + "_" + roomGUID + "_" + RoundGUID + "_" + lastcardids + "_" + lasttype.ToString());
            List<HandCard> hclist = ArrageCards(CardID);
            if (hclist == null || hclist.Count == 0)
                return GDYConsts.ReturnDefine.UNCONFIRMCARDS.ToString();
            HandCard currenthc=new HandCard();
            if (hclist.Count > 1)
            {
                if (string.IsNullOrEmpty(ArrageCardID))
                {
                    //让用户确认
                    StringBuilder sb = new StringBuilder();
                    foreach (HandCard hc in hclist)
                    {
                        sb.Append(hc.ToIds()).Append("|");
                    }
                    return "1|" + sb.ToString().TrimEnd('|');
                }
                else
                {
                    bool convertok = false;
                    foreach (HandCard hc in hclist)
                    {
                        if (hc.ToIds() == ArrageCardID)
                        {
                            currenthc = hc;
                            convertok = true;
                        }
                    }
                    if (!convertok)
                        return GDYConsts.ReturnDefine.HANDCARDCHANGED.ToString();
                }
            }
            else
                currenthc = hclist[0];
            if (string.IsNullOrEmpty(lastcardids))
            {
                iOut = new RoomDA().Discard(UserID, CardID, (int)currenthc.Type, currenthc.ToIds(), roomGUID, RoundGUID, lastcardids, lasttype);
                if (iOut == GDYConsts.ReturnDefine.SUCCESS)
                    return "0|" + currenthc.ToIds();
                return iOut.ToString();
            }
            else
            {
                //需比较
                var lids=lastcardids.Split(',');
                List<Card> lastcards = (from c in GetCardsInstance() where lids.Contains(c.CardID.ToString()) orderby c.CardNum,c.CardID select c).ToList();
                HandCard lasthand=new HandCard(){ Cards=lastcards, Type=(HandCardType)lasttype};
                AbstractHDCreator ct;
                if (currenthc.Type == HandCardType.Single)
                    ct = new SingleCreator();
                else if(currenthc.Type==HandCardType.Double)
                    ct = new DoubleCreator();
                else if(currenthc.Type==HandCardType.Straight)
                    ct = new StraightCreator();
                else
                    ct = new BombCreator();
                if (ct.CompareHandCard(lasthand, currenthc) == GDYConsts.ReturnDefine.SUCCESS)
                {
                    iOut = new RoomDA().Discard(UserID, CardID, (int)currenthc.Type, currenthc.ToIds(), roomGUID, RoundGUID, lastcardids, lasttype);
                    if (iOut == GDYConsts.ReturnDefine.SUCCESS)
                        return "0|" + currenthc.ToIds();
                    return iOut.ToString();
                }
                else
                    return GDYConsts.ReturnDefine.HANDCARDCOMPAREWRONG.ToString();
            }
        }

        public List<HandCard> ArrageCards(string cardids)
        {
            var cards = GetSortedCards(cardids);
            List<HandCard> hclist = new List<HandCard>();
            AbstractHDCreator ct = new BombCreator(new StraightCreator(new DoubleCreator(new SingleCreator())));
            ct.CreateHandCard(cards, GetCardsInstance(), hclist); 
            return hclist;
        }

        public List<Card> GetSortedCards(string cardids)
        {
            var ids=cardids.Split(',');
            if (ids.Count() <= 0 || ids.Count() > 6)
            {
                Log.Error("打出了错误的牌数");
                throw new Exception("打出了错误的牌数");
            }
            var cards = (from c in GetCardsInstance() where ids.Contains(c.CardID.ToString()) &&c.CardType<=6 orderby c.CardNum,c.CardType select c).ToList <Card>();
            if(cards.Count!=ids.Count())
            {
                Log.Error("打出了错误的牌类型");
                throw new Exception("打出了错误的牌类型");
            }
            return cards;
        }

        public int Chat(string uid, string roomguid, string chatcontent)
        {
            //检查长度，sql防注入
            if(string.IsNullOrEmpty(chatcontent))
                return 0;
            if (chatcontent.Length > 100)
                chatcontent = chatcontent.Substring(0, 100);
            chatcontent = NWN.GDY.Service.Common.SDString.SqlFilter(chatcontent, true).Trim();
            return new RoomDA().Chat(uid, roomguid, chatcontent);
        }

        public string GetCoinName(int CoinID)
        {
            return new RoomDA().GetCoinName(CoinID);
        }
    }
}
